using System.Reflection;
using Mbs.ComponentModel.Container.Context;
using Mbs.Reflection;

namespace Mbs.ComponentModel.Container.Injection
{
    public class MethodBaseInject<TMethod> : InjectAdapter<TMethod> where TMethod : MethodBase
    {
        protected override void DoExecute(IInjectContext<TMethod> ctx)
        {
            foreach (var pair in ctx.Members) 
                OnInvoke(pair.Key, ctx.Instance, GetParameters(pair.Key.GetParameters()));
        }

        protected virtual void OnInvoke(TMethod method, object instance, object[] args)
        {
            method.Invoke(instance, args);
        }

        protected virtual object[] GetParameters(ParameterInfo[] ps)
        {
            int length = ps.Length;
            object[] result = new object[length];
            foreach (var p in ps)
            {
                var att = p.GetAttribute<InjectAttribute>(false);
                if (att == null
                    || string.IsNullOrEmpty(att.Id)
                    || !Kernel.HasRegister(att.Id))
                    result[p.Position] = Kernel.Get(p.ParameterType);
                else
                    result[p.Position] = Kernel.Get(att.Id);
            }
            return result;
        }
    }
}
